
Object.defineProperty(exports, "__esModule", { value: true });
/**
* @module authManager
* @author: Hjava
* @description: 登录数据管理模块
* @since: 2018-07-16 20:59:35
*/
var constant_1 = __webpack_require__(/*! _login/constant */ "./src/core/login/constant.ts");
var session_1 = __webpack_require__(/*! _login/session */ "./src/core/login/session.ts");
var analytics_1 = __webpack_require__(/*! _util/analytics */ "./src/core/utils/analytics.ts");
var constant_2 = __webpack_require__(/*! _util/constant */ "./src/core/utils/constant.ts");
var eventEmitter_1 = __webpack_require__(/*! _util/eventEmitter */ "./src/core/utils/eventEmitter.ts");
var owlController_1 = __webpack_require__(/*! _util/owlController */ "./src/core/utils/owlController.ts");
var userData_1 = __webpack_require__(/*! _util/userData */ "./src/core/utils/userData.ts");
var log_1 = __webpack_require__(/*! ./../utils/log */ "./src/core/utils/log.ts");
var active_report_1 = __webpack_require__(/*! ../statistics/active-report */ "./src/core/statistics/active-report.ts");
var login_report_1 = __webpack_require__(/*! ../statistics/login-report */ "./src/core/statistics/login-report.ts");
var localData_1 = __webpack_require__(/*! _util/localData */ "./src/core/utils/localData.ts");
// 【暂定值】消息发送往返时长 P99 为 420 ms，单向为 210 ms，避免误判设置此值为 500 ms
var kickOffWithSameDeviceIdDelayTime = 500;
// 登录超时时间
var TIMEOUT = 30 * 1000;
var AuthManager = /** @class */ (function () {
    function AuthManager(connection) {
        this._authenticationData = {};
        this._protocols = {
            passport: session_1.default.PassportReq,
            uid: session_1.default.UidReq,
            visitor: session_1.default.VisitorReq
        };
        this._timeoutHandle = 0;
        this._lastAuthSuccessTime = 0;
        this._connection = connection;
        eventEmitter_1.default.on(constant_2.LOGIN_STATUS_CHANGE_EVENT, this._onConnectionStatusChange.bind(this));
        eventEmitter_1.default.on(constant_1.default.Login.PLOGINBYPASSPORTRES_URI, this._onAuthSuccess.bind(this));
        eventEmitter_1.default.on(constant_1.default.Login.PLOGINBYUIDRES_URI, this._onAuthSuccess.bind(this));
        eventEmitter_1.default.on(constant_1.default.Login.PVISITORLOGINRES_URI, this._onAuthSuccess.bind(this));
        eventEmitter_1.default.on(constant_1.default.Login.PKICKOFF_URI, this._onKickOff.bind(this));
        eventEmitter_1.default.on(constant_1.default.Login.PKICKOFFWITHSAMEDEVICEID_URI, this._onKickOffWithSameDevice.bind(this));
        active_report_1.default.reportActive('init');
    }
    AuthManager.prototype.loginWithPassport = function (passport, password, supportMultiDevices) {
        if (passport === void 0) { passport = ''; }
        if (password === void 0) { password = ''; }
        if (supportMultiDevices === void 0) { supportMultiDevices = false; }
        log_1.default.log('authManager::loginWithPassport passport:' + passport + ' supportMultiDevices:' + supportMultiDevices);
        this._register('passport', {
            passport: passport,
            password: password,
            supportMultiDevices: supportMultiDevices
        });
        active_report_1.default.reportActive('connect');
        this._authenticate();
    };
    AuthManager.prototype.loginWithUid = function (uid, token, supportMultiDevices) {
        if (uid === void 0) { uid = ''; }
        if (token === void 0) { token = ''; }
        if (supportMultiDevices === void 0) { supportMultiDevices = false; }
        log_1.default.log('authManager::loginWithUid uid:' + uid + ' supportMultiDevices:' + supportMultiDevices);
        this._register('uid', {
            uid: uid,
            cookie: token,
            supportMultiDevices: supportMultiDevices
        });
        active_report_1.default.reportActive('connect');
        this._authenticate();
    };
    AuthManager.prototype.loginWithVisitor = function (uid, xsid) {
        if (uid === void 0) { uid = ''; }
        if (xsid === void 0) { xsid = ''; }
        log_1.default.log('authManager::loginWithVisitor uid:' + uid);
        this._register('visitor', {
            uid: uid,
            xsid: xsid
        });
        active_report_1.default.reportActive('connect');
        this._authenticate();
    };
    AuthManager.prototype._register = function (type, data) {
        if (type === void 0) { type = ''; }
        this._authenticationData = {
            type: type,
            data: data
        };
        login_report_1.default.setRunReport(true);
    };
    AuthManager.prototype._createAuthData = function () {
        if (!this._authenticationData.type) {
            return null;
        }
        var ret = {
            type: '',
            data: null
        };
        var uid = userData_1.default.get('uid');
        var cookie = userData_1.default.get('xsid');
        if (this._authenticationData.type && this._authenticationData.type == 'passport' && uid && uid != '' && cookie && cookie != '') {
            ret.type = 'uid';
            ret.data = {
                uid: uid,
                cookie: cookie,
                supportMultiDevices: this._authenticationData.data ? this._authenticationData.data.supportMultiDevices : false
            };
        }
        else {
            ret.type = this._authenticationData.type;
            ret.data = this._authenticationData.data;
        }
        return ret;
    };
    AuthManager.prototype._getAuthenticationData = function (authData) {
        return new this._protocols[authData.type](authData.data);
    };
    AuthManager.prototype._authenticate = function () {
        var _this = this;
        // 如果在收到登录数据时长连接没有建立,那么等待长连接建立即可
        if (this._connection.getStatus() === constant_2.LOGIN_STATUS.CONNECTED && this._authenticationData.type) {
            var authData_1 = this._createAuthData();
            if (!authData_1) {
                log_1.default.error('authManager::_authenticate _createAuthData error');
                return;
            }
            var reportPassport_1 = authData_1.data.uid ? authData_1.data.uid : authData_1.data.passport;
            var reportId_1 = authData_1.data.cookie ? authData_1.data.cookie.slice(0, 15) : void 0;
            analytics_1.default.report({
                nm: 'login_send_start',
                val: {
                    type: this._connection && this._connection.connectionType === 'websocket' ? 2 : 3,
                    msgtype: authData_1 && authData_1.type == 'uid' ? 2 : 1,
                    passport: reportPassport_1,
                    id: reportId_1,
                    websocketId: userData_1.default.get('websocketId')
                }
            });
            login_report_1.default.reportAuthStart();
            log_1.default.log('authManager::_authenticate send auth request' + ' type:' + authData_1.type + ' reportPassport:' + reportPassport_1 + ' reportId:' + reportId_1);
            this._connection.send(this._getAuthenticationData(authData_1), false);
            this._reset();
            this._connection._changeConnectStatus(constant_2.LOGIN_STATUS.AUTHENTICATING, 'authenticating');
            this._timeoutHandle = setTimeout(function () {
                // 认证超时断开当前连接，反馈给上层业务登录失败,断开当前的连接,重新进入断线重连流程
                analytics_1.default.report({
                    nm: 'login_auth_timeout',
                    val: {
                        type: _this._connection && _this._connection.connectionType === 'websocket' ? 2 : 3,
                        msgtype: authData_1 && authData_1.type == 'uid' ? 2 : 1,
                        passport: reportPassport_1,
                        id: reportId_1,
                        websocketId: userData_1.default.get('websocketId')
                    }
                });
                login_report_1.default.reportAuthTimeout();
                log_1.default.log('authManager::_authenticate::login_auth_timeout');
                _this._connection._changeConnectStatus(constant_2.LOGIN_STATUS.DISCONNECTED, 'authenticate_timeout');
            }, TIMEOUT);
            userData_1.default.set('_startSendLoginTime', Date.now());
        }
    };
    AuthManager.prototype.logout = function () {
        log_1.default.log('authManager::logout');
        this._connection.send(new session_1.default.LogoutReq({
            uid: userData_1.default.get('uid')
        }));
        userData_1.default.set('xsid', '');
        this._authenticationData = {};
        login_report_1.default.setRunReport(false);
        eventEmitter_1.default.emit('Logout');
    };
    AuthManager.prototype.logoutByFalseKickoff = function (rescode) {
        log_1.default.log('authManager::logoutByFalseKickoff rescode:' + rescode);
        eventEmitter_1.default.emit(constant_1.default.Login.PKICKOFF_URI, {
            uid: userData_1.default.get('uid'),
            appid: userData_1.default.get('appId'),
            reason: rescode
        });
    };
    AuthManager.prototype._onConnectionStatusChange = function (status) {
        if (status === void 0) { status = constant_2.LOGIN_STATUS.CONNECTING; }
        log_1.default.log('authManager::_onConnectionStatusChange status:' + status);
        switch (status) {
            case constant_2.LOGIN_STATUS.CONNECTING: {
                eventEmitter_1.default.emit(constant_2.LOGIN_EVENT.CONNECTING);
                break;
            }
            case constant_2.LOGIN_STATUS.CONNECTED: {
                eventEmitter_1.default.emit(constant_2.LOGIN_EVENT.CONNECTED);
                this._authenticate();
                break;
            }
            case constant_2.LOGIN_STATUS.AUTHENTICATING: {
                eventEmitter_1.default.emit(constant_2.LOGIN_EVENT.AUTHENTICATING);
                break;
            }
            case constant_2.LOGIN_STATUS.DISCONNECTED: {
                login_report_1.default.reportAuthSuccess();
                this._reset();
                this._lastAuthSuccessTime = Date.now();
                eventEmitter_1.default.emit(constant_2.LOGIN_EVENT.DISCONNECT);
                break;
            }
        }
    };
    AuthManager.prototype._onAuthSuccess = function (res) {
        this._reset();
        if (res.rescode === constant_2.RESCODE.RES_SUCCESS) {
            log_1.default.log('authManager::_onAuthSuccess success uid:' + res.uid);
            this._connection._changeConnectStatus(constant_2.LOGIN_STATUS.AUTHENTICATED, 'authenticated');
            eventEmitter_1.default.emit(constant_2.LOGIN_EVENT.AUTH_SUCCESS, res.uid, res.cookie, userData_1.default.get('appId'), res.altoken, res.channel_map);
            userData_1.default.setAll({
                uid: res.uid,
                xsid: res.cookie,
                altoken: res.altoken,
                channelMap: res.channel_map
            });
            analytics_1.default.setAnalyticsUid(res.uid);
            localData_1.default.set('last_login_success_uid', res.uid + "");
            var startLoginTime = userData_1.default.get('_startLoginTime');
            var _startSendLoginTime = userData_1.default.get('_startSendLoginTime');
            var _startConnectToLoginTime = userData_1.default.get('_startConnectToLoginTime');
            analytics_1.default.report({
                nm: 'login_success',
                val: {
                    type: this._connection.connectionType === 'websocket' ? 2 : 3,
                    mid: userData_1.default.get('uid'),
                    xsid: userData_1.default.get('xsid').slice(0, 15),
                    id: userData_1.default.get('altoken').slice(0, 15),
                    exchange_time: _startSendLoginTime ? Date.now() - _startSendLoginTime : void 0,
                    login_time: startLoginTime > 0 ? Date.now() - startLoginTime : void 0,
                    time: _startConnectToLoginTime ? Date.now() - _startConnectToLoginTime : void 0,
                    websocketId: userData_1.default.get('websocketId')
                }
            });
            userData_1.default.remove('_startLoginTime');
            userData_1.default.remove('_startConnectToLoginTime');
            owlController_1.default.send({
                name: 'login_finished',
                value: _startConnectToLoginTime > 0 ? Date.now() - _startConnectToLoginTime : 0,
                tag: {
                    status: 1
                }
            });
            login_report_1.default.reportAuthSuccess();
        }
        else {
            log_1.default.log('authManager::_onAuthSuccess fail code:' + res.rescode);
            analytics_1.default.report({
                nm: 'login_authfail',
                val: {
                    code: res.rescode,
                    type: this._connection.connectionType === 'websocket' ? 2 : 3,
                    id: this._authenticationData.cookie ? this._authenticationData.cookie.slice(0, 15) : void 0,
                    websocketId: userData_1.default.get('websocketId'),
                },
            });
            login_report_1.default.reportAuthFail({ resultCode: res.rescode }); // 不要放到_changeConnectStatus后面
            // 登录失败后清理登录数据,避免无效数据重复登录
            // 在前端登录超时,后端30s没有响应(rescode=-2)的情况下也会进入此逻辑,不进行自动重试是为了避免导致后端的雪崩效应,需要业务自己调用loginWithPassport进行重试,具体文档见:https://docs.sankuai.com/dx-sdk-web/login/#_14
            userData_1.default.set('xsid', '');
            this._authenticationData = {};
            login_report_1.default.setRunReport(false);
            eventEmitter_1.default.emit('AuthFail', res.rescode);
            this._connection._changeConnectStatus(constant_2.LOGIN_STATUS.DISCONNECTED, 'authenticate_fail');
            owlController_1.default.send({
                name: 'login_finished',
                value: res.rescode,
                tag: {
                    status: 0,
                },
            });
        }
    };
    AuthManager.prototype._onKickOff = function (res) {
        log_1.default.log('authManager::_onKickOff res:' + res);
        this._connection._changeConnectStatus(constant_2.LOGIN_STATUS.DISCONNECTED, 'terminated');
        userData_1.default.set('xsid', '');
        this._authenticationData = {};
        login_report_1.default.setRunReport(false);
        eventEmitter_1.default.emit('KickOff', {
            uid: res.uid,
            appid: res.appid,
            reason: res.reason
        });
        this._reset();
        analytics_1.default.report({
            nm: 'login_kickoff',
            val: {
                code: res.reason,
                xsid: userData_1.default.get('xsid'),
                id: userData_1.default.get('altoken').slice(0, 15),
                websocketId: userData_1.default.get('websocketId')
            }
        });
        owlController_1.default.send({
            name: 'login_kickoff',
            value: res.reason
        });
    };
    AuthManager.prototype._onKickOffWithSameDevice = function (res) {
        log_1.default.log('authManager::_onKickOffWithSameDevice res:' + res);
        var now = Date.now();
        if (now - this._lastAuthSuccessTime < kickOffWithSameDeviceIdDelayTime) {
            analytics_1.default.report({
                nm: 'login_kickoff_same_in_delay',
                val: {
                    code: -1,
                    xsid: userData_1.default.get('xsid'),
                    id: userData_1.default.get('altoken').slice(0, 15),
                    websocketId: userData_1.default.get('websocketId')
                }
            });
            this._connection._changeConnectStatus(constant_2.LOGIN_STATUS.DISCONNECTED, 'login_kickoff_same_in_delay');
            return;
        }
        this._connection._changeConnectStatus(constant_2.LOGIN_STATUS.DISCONNECTED, 'terminated');
        userData_1.default.set('xsid', '');
        this._authenticationData = {};
        login_report_1.default.setRunReport(false);
        eventEmitter_1.default.emit('KickOffWithSameDeviceId', {
            uid: res.uid,
            appId: res.appId,
            deviceType: res.deviceType
        });
        this._reset();
        analytics_1.default.report({
            nm: 'login_kickoff_same',
            val: {
                code: -1,
                xsid: userData_1.default.get('xsid'),
                id: userData_1.default.get('altoken').slice(0, 15),
                websocketId: userData_1.default.get('websocketId')
            }
        });
        owlController_1.default.send({
            name: 'login_kickoff_same',
            value: res.reason
        });
    };
    AuthManager.prototype._reset = function () {
        clearTimeout(this._timeoutHandle);
        this._timeoutHandle = 0;
    };
    return AuthManager;
}());
exports.default = AuthManager;


//# sourceURL=webpack://MTDX/./src/core/login/authManager.ts?